package com.s7.widget.banner;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.s7.widget.R;
import com.s7.widget.banner.adapter.CBPageAdapter;
import com.s7.widget.banner.helper.CBLoopScaleHelper;
import com.s7.widget.banner.holder.CBViewHolderCreator;
import com.s7.widget.banner.listener.CBPageChangeListener;
import com.s7.widget.banner.listener.OnBannerClickListener;
import com.s7.widget.banner.listener.OnPageChangeListener;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 页面翻转控件，极方便的广告栏
 * 支持无限循环，自动翻页，翻页特效
 * @author Sai 支持自动翻页
 */
public class ConvenientBanner<T> extends RelativeLayout {

    /**
     * 数据
     */
//    private List<T> mDatas;

    /**
     * 指示器图片
     */
    private int[] page_indicatorId;

    /**
     * 单个指示器 集合
     */
    private ArrayList<ImageView> mPointViews = new ArrayList<ImageView>();

    /**
     * 适配器
     */
    private CBPageAdapter pageAdapter;

    /**
     * 自定义 viewPager
     */
    private CBLoopViewPager viewPager;

    /**
     * 指示器容器
     */
    private ViewGroup loPageTurningPoint;

    /**
     * 切换时间
     */
    private long autoTurningTime = -1;
    private boolean turning;

    /**
     * 是否可翻页
     */
    private boolean canTurn = false;

    /**
     * 循环状态
     */
    private boolean canLoop = true;

    private CBLoopScaleHelper cbLoopScaleHelper;
    private CBPageChangeListener pageChangeListener;
    private OnPageChangeListener onPageChangeListener;
    private AdSwitchTask adSwitchTask;

    public enum PageIndicatorAlign {
        ALIGN_PARENT_LEFT, ALIGN_PARENT_RIGHT, CENTER_HORIZONTAL
    }

    public ConvenientBanner(Context context) {
        super(context);
        init(context);
    }

    public ConvenientBanner(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ConvenientBanner);
        canLoop = a.getBoolean(R.styleable.ConvenientBanner_canLoop, true);
        autoTurningTime = a.getInteger(R.styleable.ConvenientBanner_autoTurningTime, -1);
        a.recycle();
        init(context);
    }

    private void init(Context context) {
        View hView = LayoutInflater.from(context).inflate(
                R.layout.banner_convenient, this, true);
        viewPager = hView.findViewById(R.id.convenient_pager);
        loPageTurningPoint = hView.findViewById(R.id.convenient_point);
        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
        viewPager.setLayoutManager(linearLayoutManager);

        cbLoopScaleHelper = new CBLoopScaleHelper();

        adSwitchTask = new AdSwitchTask(this);
    }

    /**
     * 设置方向 （左右/上下）
     * @param layoutManager
     * @return
     */
    public ConvenientBanner setLayoutManager(RecyclerView.LayoutManager layoutManager) {
        viewPager.setLayoutManager(layoutManager);
        return this;
    }

    /**
     * 设置适配器（布局）和数据
     * @param holderCreator 适配器（布局）
     * @return
     */
    public ConvenientBanner setHolderCreator(CBViewHolderCreator holderCreator) {
        pageAdapter = new CBPageAdapter(holderCreator, canLoop);
        viewPager.setAdapter(pageAdapter);
        if (page_indicatorId != null) {
            setPageIndicator(page_indicatorId);
        }
        cbLoopScaleHelper.setFirstItemPos(canLoop ? pageAdapter.getRealItemCount() : 0);
        cbLoopScaleHelper.attachToRecyclerView(viewPager);
        return this;
    }

    /**
     * 设置数据
     * @param datas 数据
     * @return
     */
    public ConvenientBanner setData(List<T> datas) {
        if (pageAdapter != null) {
            pageAdapter.notifyData(datas);
            notifyDataSetChanged();
        }
        return this;
    }

    /**
     * 设置是否循环
     * @param canLoop
     * @return
     */
    public ConvenientBanner setCanLoop(boolean canLoop){
        this.canLoop = canLoop;
        if (pageAdapter != null) {
            pageAdapter.setCanLoop(canLoop);
            notifyDataSetChanged();
        }
        return this;
    }

    /**
     * 获取循环状态
     * @return
     */
    public boolean isCanLoop(){
        return canLoop;
    }

    /**
     * 通知数据变化
     */
    public void notifyDataSetChanged() {
        if (pageAdapter == null) {
            return;
        }
        pageAdapter.notifyDataSetChanged();
        if (page_indicatorId != null) {
            setPageIndicator(page_indicatorId);
        }
        cbLoopScaleHelper.setCurrentItem(canLoop ? pageAdapter.getRealItemCount() : 0);
    }

    /**
     * 设置底部指示器是否可见
     * @param visible
     */
    public ConvenientBanner setPointViewVisible(boolean visible) {
        loPageTurningPoint.setVisibility(visible ? View.VISIBLE : View.GONE);
        return this;
    }

    /**
     * 底部指示器资源图片
     * @param page_indicatorId
     */
    public ConvenientBanner setPageIndicator(int[] page_indicatorId) {
        return setPageIndicator(page_indicatorId, 0);
    }

    /**
     * 底部指示器资源图片 及 离底部的距离
     * @param page_indicatorId
     * @param bottom
     */
    public ConvenientBanner setPageIndicator(int[] page_indicatorId, int bottom) {
        loPageTurningPoint.removeAllViews();
        if (bottom > 0) {
            loPageTurningPoint.setPadding(0, 0, 0, bottom);
        }
        mPointViews.clear();
        this.page_indicatorId = page_indicatorId;
        if (pageAdapter == null) {
            return this;
        }
        for (int count = 0; count < pageAdapter.getRealItemCount(); count++) {
            // 翻页指示的点
            ImageView pointView = new ImageView(getContext());
            pointView.setPadding(5, 0, 5, 0);
            if (cbLoopScaleHelper.getFirstItemPos() % pageAdapter.getRealItemCount() == count) {
                pointView.setImageResource(page_indicatorId[1]);
            } else {
                pointView.setImageResource(page_indicatorId[0]);
            }
            mPointViews.add(pointView);
            loPageTurningPoint.addView(pointView);
        }
        pageChangeListener = new CBPageChangeListener(mPointViews, page_indicatorId);
        cbLoopScaleHelper.setOnPageChangeListener(pageChangeListener);

        /**
         * 翻页监听
         */
        if (onPageChangeListener != null)
            pageChangeListener.setOnPageChangeListener(onPageChangeListener);
        return this;
    }

    /**
     * 获取翻页监听
     * @return
     */
    public OnPageChangeListener getOnPageChangeListener() {
        return onPageChangeListener;
    }

    /**
     * 设置翻页监听器
     * @param onPageChangeListener
     * @return
     */
    public ConvenientBanner setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {
        this.onPageChangeListener = onPageChangeListener;
        //如果有默认的监听器（即是使用了默认的翻页指示器）则把用户设置的依附到默认的上面，否则就直接设置
        if (pageChangeListener != null)
            pageChangeListener.setOnPageChangeListener(onPageChangeListener);
        else cbLoopScaleHelper.setOnPageChangeListener(onPageChangeListener);
        return this;
    }

    /**
     * 监听item点击
     * @param onBannerClickListener
     */
    public ConvenientBanner setOnItemClickListener(final OnBannerClickListener onBannerClickListener) {
        if (pageAdapter != null) {
            pageAdapter.setOnBannerClickListener(onBannerClickListener);
        }
        return this;
    }

    /**
     * 获取当前页对应的position
     * @return
     */
    public int getCurrentItem() {
        return cbLoopScaleHelper.getRealCurrentItem();
    }

    /**
     * 设置当前页对应的position
     * @return
     */
    public ConvenientBanner setCurrentItem(int position, boolean smoothScroll) {
        if (pageAdapter != null) {
            cbLoopScaleHelper.setCurrentItem(canLoop ?
                    pageAdapter.getRealItemCount() + position : position, smoothScroll);
        }
        return this;
    }

    /**
     * 设置第一次加载当前页对应的 position
     * setPageIndicator 之前使用
     * @return
     */
    public ConvenientBanner setFirstItemPos(int position) {
        return setCurrentItem(position, false);
    }

    /**
     * 设置指示器的方向
     * @param align 三个方向：居左 （RelativeLayout.ALIGN_PARENT_LEFT），
     *                        居中 （RelativeLayout.CENTER_HORIZONTAL），
     *                        居右 （RelativeLayout.ALIGN_PARENT_RIGHT）
     * @return
     */
    public ConvenientBanner setPageIndicatorAlign(PageIndicatorAlign align) {
        LayoutParams layoutParams = (LayoutParams) loPageTurningPoint.getLayoutParams();
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,
                align == PageIndicatorAlign.ALIGN_PARENT_LEFT ? RelativeLayout.TRUE : 0);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,
                align == PageIndicatorAlign.ALIGN_PARENT_RIGHT ? RelativeLayout.TRUE : 0);
        layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
                align == PageIndicatorAlign.CENTER_HORIZONTAL ? RelativeLayout.TRUE : 0);
        loPageTurningPoint.setLayoutParams(layoutParams);
        return this;
    }

    /***
     * 是否开启了翻页
     * @return
     */
    public boolean isTurning() {
        return turning;
    }

    /***
     * 设置翻页时间 并 开始翻页
     * @param autoTurningTime 自动翻页时间
     * @return
     */
    public ConvenientBanner startTurning(long autoTurningTime) {
        if (autoTurningTime < 0) return this;
        //如果是正在翻页的话先停掉
        if (turning) {
            stopTurning();
        }
        //设置可以翻页并开启翻页
        canTurn = true;
        this.autoTurningTime = autoTurningTime;
        turning = true;
        postDelayed(adSwitchTask, autoTurningTime);
        return this;
    }

    /**
     * 开始翻页
     * @return
     */
    public ConvenientBanner startTurning() {
        startTurning(autoTurningTime);
        return this;
    }

    /**
     * 停止翻页
     */
    public void stopTurning() {
        turning = false;
        removeCallbacks(adSwitchTask);
    }

    /**
     * 触碰控件的时候，翻页应该停止，离开的时候如果之前是开启了翻页的话则重新启动翻页
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE) {
            // 开始翻页
            if (canTurn) startTurning(autoTurningTime);
        } else if (action == MotionEvent.ACTION_DOWN) {
            // 停止翻页
            if (canTurn) stopTurning();
        }
        return super.dispatchTouchEvent(ev);
    }

    static class AdSwitchTask implements Runnable {

        private final WeakReference<ConvenientBanner> reference;

        AdSwitchTask(ConvenientBanner convenientBanner) {
            this.reference = new WeakReference<ConvenientBanner>(convenientBanner);
        }

        @Override
        public void run() {
            ConvenientBanner convenientBanner = reference.get();

            if (convenientBanner != null) {
                if (convenientBanner.viewPager != null && convenientBanner.turning) {
                    int page = convenientBanner.cbLoopScaleHelper.getCurrentItem() + 1;
                    convenientBanner.cbLoopScaleHelper.setCurrentItem(page, true);
                    convenientBanner.postDelayed(convenientBanner.adSwitchTask, convenientBanner.autoTurningTime);
                }
            }
        }
    }

}
